package my.game.Descension;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JComponent;

@SuppressWarnings("serial")
public class Display extends JComponent implements Constants{

	final int TILE_SIZE = 32;
	final int SCREEN_SIZE = TILE_SIZE * 20;
	
	private int menuPosition = 0; // Initial menu position.
	
	private Creature player;
	private LevelLoader level;
	private Graphics2D g2d;
	private Graphics2D battlegfx; // For drawing HUD, etc.
	
	// testing
	Sprite map = new Sprite("water");
	
	public Display() {
		setLayout(null); // Absolute positioning
		setVisible(true);
		setFocusable(false);
		setBackground(Color.black);
		setSize(SCREEN_SIZE + 12, SCREEN_SIZE + 12);
		
		
	}
	
	public void paint(Graphics g) {
		super.paint(g);
		g2d = (Graphics2D)g;
		battlegfx = (Graphics2D)g;
		
		
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		battlegfx.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		if (player.isOnOverworld()) {
			drawMap();
			drawPlayer();
			drawInfoBar(player.getX(), player.getY());
			if (player.InventoryOpen())
				drawInventory();
		}
		
		if (player.isInBattle()) {
			drawBattlefield();
			drawEnemies();
			drawPlayerBattle();
			drawHUD();
		}
		//g2d.setColor(Color.yellow);
		//g2d.drawRect(player.getX()*32, player.getY()*32, 32, 32);
		g2d.dispose();
		battlegfx.dispose();
	}
	
	public void drawPlayer() {
		
		g2d.drawImage(player.getSprite().getImage(), player.getX() * TILE_SIZE, 
					player.getY() * TILE_SIZE, 
					null);
		
		
	}
	
	public void drawMap() {
		int inc = 0;
		Sprite tiles[] = level.getTiles();
		for (int i = 0; i < 20; i++) {
			for (int k = 0; k < 20; k++) {
				if (tiles[inc].isBackground()) {
				g2d.drawImage(tiles[inc].getImage(), k*32, i*32, null);
				}
				else {
					// For drawing things in foreground, i.e trees.
					g2d.drawImage(tiles[inc].getBackgroundImage(), k*32, i*32, null);
					g2d.drawImage(tiles[inc].getImage(), k*32, i*32, null);
				}
				inc++;
				//g2d.drawImage(map.getImage(), i*32, k*32, null);
			}
			
		}
	}
	
	
	// Draws a title bar above locations when standing on them. Ex, "Town".
	public void drawInfoBar(int x, int y) {
		String info = level.findSprite(x, y).getInfo();
		
		if (info != null) {
		//g2d.setColor(Color.gray);
		//g2d.fillRect(x*32, (y-1)*32, 60, 30);
		g2d.setColor(Color.white);
		g2d.drawString(info, x*32, y*32);
		}
	}
	
	// Draws the inventory. Testing to make sure it'll work.
	// TODO: Add actuall GUI code for Inventory.
	public void drawInventory() {
		g2d.fillRect(300, 300, 200, 100);
	}
	
	// Draws error to the screen for debug purposes.
	public void drawError(String error) {
		
	}
	
	// Debug
	public void drawDoorLocation(Sprite door) {
		g2d.drawRect(door.getX(), door.getY(), 32, 32);
	}
	
	// Sets the player object to the one used by the Controller class. Makes sure we
	// have the same instance.
	public void setPlayer(Creature player) {
		this.player = player;
	}
	
	public void setMap (LevelLoader level) {
		this.level = level;
	}
	
	
	// Battle code
	
	
	public void drawBattlefield(){
	
		// Draw a silly background.
		g2d.drawImage(new Sprite("battletest").getImage(), 0, 0, null);
		
	}
	
	public void drawPlayerBattle() {
		// For now, draw sprite.
		g2d.drawImage(player.getSprite().getImage(), 500, 500, null);
	}
	
	public void drawEnemies() {
		// Draw a slug for now.
		g2d.drawImage(new Sprite("slug").getImage(), 200, 500, null);
	}
	
	// All uber hard coded right now.
	public void drawHUD() {
		
		// Create a test array of menu options.
		String menuOptions[] = {"Menu1", "Menu2", "Menu3"};
		
		// K > 0, move cursor up (increment menu) else move down menu.
		int k = player.getCursorDir();
		
		menuPosition += k;
		if (menuPosition < 0)
			menuPosition = 0;
		if (menuPosition > menuOptions.length - 1)
			menuPosition = menuOptions.length - 1;
		
		g2d.setColor(Color.red);
		g2d.fillArc(390, 420, 200, 200, 100, 160);
		g2d.setColor(Color.ORANGE);
		
		BufferedImage buffer = new BufferedImage(50, 110, BufferedImage.TYPE_INT_ARGB);
		Graphics2D menu = (Graphics2D)buffer.createGraphics();
		menu.setColor(Color.black);

		if (menuPosition < menuOptions.length -1)
		menu.drawString(menuOptions[menuPosition + 1], 0, 10);
		else menu.drawString(menuOptions[menuPosition], 0, 10);
		menu.dispose();
		
		BufferedImage buffer2 = new BufferedImage(80,10, BufferedImage.TYPE_INT_ARGB);
		Graphics2D menu2 = (Graphics2D)buffer2.createGraphics();
		menu2.setPaint(Color.black);
		if (menuPosition < menuOptions.length -1)
		menu2.drawString(menuOptions[menuPosition + 1], 0, 10);
		else menu.drawString(menuOptions[menuPosition], 0, 10);
		menu2.dispose();
		
		double rotationRequired = Math.toRadians(45);
		double locationX = buffer.getWidth() / 2;
		double locationY = buffer.getHeight() / 2;
		AffineTransform tx = AffineTransform.getRotateInstance(rotationRequired, locationX, locationY);
		AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);

		double rotationRequired2 = Math.toRadians(-45);
		double locationX2 = buffer2.getWidth() / 2;
		double locationY2 = buffer2.getHeight() / 2;
		AffineTransform tx2 = AffineTransform.getRotateInstance(rotationRequired2, locationX2, locationY2);
		AffineTransformOp op2 = new AffineTransformOp(tx2, AffineTransformOp.TYPE_BILINEAR);

		
		battlegfx.drawImage(op.filter(buffer,null),390,480,null);
		battlegfx.drawImage(op2.filter(buffer2,null),430,545,null);
		battlegfx.drawString(menuOptions[menuPosition], 420, 530);
		battlegfx.drawString("" + k, 400,400);
	}
	
	
	public void drawDialog(String dialog) {
		
		// Decent parchment-ey color
		g2d.setColor(Color.getHSBColor(25, 100, 25));
		g2d.fillRect(DIALOG_X, DIALOG_Y, DIALOG_WIDTH, DIALOG_HEIGHT);
		
		// Create crappy border for now.
		g2d.setColor(Color.darkGray);
		g2d.fillRect(DIALOG_X, DIALOG_Y, 20, DIALOG_HEIGHT);
		g2d.fillRect(DIALOG_X, DIALOG_Y, DIALOG_WIDTH, 20);
		g2d.fillRect(DIALOG_X + DIALOG_WIDTH - 20, DIALOG_Y, 20, DIALOG_HEIGHT);
		g2d.fillRect(DIALOG_X, DIALOG_Y + DIALOG_HEIGHT - 20, DIALOG_WIDTH, 20);
		
		// Load and draw portrait and name. 
		// TODO: Make portrait an argument
		ImageIcon ii = new ImageIcon("sprites/"+ "charPortrait.png");
		g2d.drawImage(ii.getImage(),PORTRAIT_X, PORTRAIT_Y, null);
		g2d.drawString("Man", PORTRAIT_NAME_X, PORTRAIT_NAME_Y);
		
		// Draw text
		g2d.drawString("BLAH BLAH BLAH BLAH BLAH BLAH", TEXT_X, TEXT_Y); // Row 1
		g2d.drawString("BLAH BLAH BLAH BLAH BLAH BLAH", TEXT_X, TEXT_Y+TEXT_ROW_HEIGHT); // Row 2
		g2d.drawString("BLAH BLAH BLAH BLAH BLAH BLAH", TEXT_X, TEXT_Y+2*TEXT_ROW_HEIGHT); // Row 3
		g2d.drawString(dialog, TEXT_X, TEXT_Y+3*TEXT_ROW_HEIGHT);
	}
	
	
	
	
	
	
}
